home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 October: Mac OS SDK / Dev.CD Oct 00 SDK1.toast / Development Kits / Mac OS / Display Manager SDK / Sample Code / Play Video Sample / RequestVideo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-16  |  20.1 KB  |  568 lines  |  [TEXT/CWIE]

  1. /*------------------------------------------------------------------------------
  2. #
  3. #    MacOS™ Sample Code
  4. #    
  5. #    Written by: Eric Anderson
  6. #    Additional Input: David Lawrence
  7. #     email: eric3@apple.com
  8. #
  9. #    Display Manager sample code
  10. #
  11. #    RequestVideo
  12. #
  13. #    RequestVideo.c    -    C Code
  14. #
  15. #    Copyright © 1995 Apple Computer, Inc.
  16. #    All rights reserved.
  17. #
  18. #    1/20/99        ewa        Updated to CWPro 3, removed slot manager sample code since
  19. #                        it is really ugly and should not be used. DM 2.0 is a MUCH
  20. #                        better way to do things today.
  21. #    1/28/97        ewa        Updated source for Metrowerks CodeWarrior 11
  22. #    6/27/96        dal        RVRequestVideoSetting() no longer requires Slot Manager DM 2.0 can be used.
  23. #    6/27/96        dal        Added check for Display Library before making DM 2.0 calls.
  24. #    5/31/95        ewa        Added RVGetCurrentVideoSetting and RVConfirmVideoRequest routines
  25. #                        to make it easy to revert back to where you came from and to give
  26. #                        the user a chance to confirm the new setting if the new mode was
  27. #                        valid (ie: the card supports it) but not safe (the monitor may not).
  28. #    5/24/95        ewa        Give the kAllValidModesBit requestFlags option for safe only or all
  29. #                        valid resolution timings.
  30. #
  31. #
  32. #
  33. #    Components:    PlayVideo.c            
  34. #                RequestVideo.c        
  35. #                RequestVideo.h        
  36. #                RequestVideo.rsrc        
  37. #
  38. #    RequestVideo demonstrates the usage of the Display Manager introduced
  39. #    with the PowerMacs and integrated into the system under System 7.5. With
  40. #    the RequestVideo sample code library, developers will be able to explore
  41. #    the Display Manager API by changing bit depth and screen resolution on
  42. #    multisync displays on built-in, NuBus, and PCI based video. Display Manager 1.0
  43. #    is built into the Systems included with the first PowerMacs up through System 7.5.
  44. #    Display Manager 2.0 is included with the release of the new PCI based PowerMacs,
  45. #    and will be included in post 7.5 System Software releases. 
  46. #    
  47. #    It is a good idea to reset the screen(s) to the original setting before exit
  48. #    since the call to RVSetVideoAsScreenPrefs() may not do the right thing under
  49. #    Display Manager 1.0 with certain video drivers.
  50. #
  51. #    For information on the use of this sample code, please the documentation in the Read Me file
  52. #
  53. ------------------------------------------------------------------------------*/
  54.  
  55. #include "RequestVideo.h"
  56.  
  57. // Internal includes
  58. #include <Dialogs.h>
  59. #include <ROMDefs.h>
  60. #include <Devices.h>
  61. #include <Errors.h>
  62. #include <Gestalt.h>
  63. #include <Memory.h>
  64. #include <Palettes.h>
  65. #include <Displays.h>
  66. #include <ConditionalMacros.h>    //DL
  67. #include <CodeFragments.h>    //DL
  68.  
  69. #define abs(x) ( ( (x) < 0 ) ? -(x) : (x) )
  70.  
  71. //--------------------------------------------------------------
  72. //
  73. // Internal defines, structs, typedefs, and routine declarations
  74. //
  75. //--------------------------------------------------------------
  76. #define        KMonoDev            0                        // false (handy definitions for gdDevType settings)
  77. #define        kColorDev            1                        // true
  78. #define        char_Enter            0x03                    // for our filter proc
  79. #define        char_Return            0x0D                    //
  80. #define        iRevertItem            1                        // User buttons
  81. #define        iConfirmItem        2                        //
  82. #define        kSecondsToConfirm    8                        // seconds before confirm dialog is taken down
  83. #define        rConfirmSwtchAlrt    2735                    // ID of alert dialog
  84.  
  85. struct DepthInfo
  86. {
  87.     VDSwitchInfoRec            depthSwitchInfo;            // This is the switch mode to choose this timing/depth
  88.     VPBlock                    depthVPBlock;                // VPBlock (including size, depth and format)
  89. };
  90. typedef struct DepthInfo DepthInfo;
  91.  
  92. struct ListIteratorDataRec
  93. {
  94.     VDTimingInfoRec            displayModeTimingInfo;        // Contains timing flags and such
  95.     unsigned long            depthBlockCount;            // How many depths available for a particular timing
  96.     DepthInfo                *depthBlocks;                // Array of DepthInfo
  97. };
  98. typedef struct ListIteratorDataRec ListIteratorDataRec;
  99.  
  100. void GetRequestTheDM2Way (        VideoRequestRecPtr requestRecPtr,
  101.                                 GDHandle walkDevice,
  102.                                 DMDisplayModeListIteratorUPP myModeIteratorProc,
  103.                                 DMListIndexType theDisplayModeCount,
  104.                                 DMListType *theDisplayModeList);
  105.  
  106. pascal void ModeListIterator (    void *userData,
  107.                                 DMListIndexType itemIndex,
  108.                                 DMDisplayModeListEntryPtr displaymodeInfo);
  109.  
  110. Boolean FindBestMatch (            VideoRequestRecPtr requestRecPtr,
  111.                                 short bitDepth,
  112.                                 unsigned long horizontal,
  113.                                 unsigned long vertical);
  114.  
  115. void GravitateMonitors (void);
  116.  
  117. pascal Boolean ConfirmAlertFilter (DialogRef dlg, EventRecord *evt, short *itemHit);
  118.  
  119. //--------------------------------------------------------------
  120. //
  121. // Implementation of sample code
  122. //
  123. //--------------------------------------------------------------
  124. OSErr RVSetVideoRequest (VideoRequestRecPtr requestRecPtr)
  125. {
  126.     Boolean            displayMgrPresent;
  127.     unsigned long    displayMgrVersion;
  128.     OSErr            err = paramErr;
  129.     Boolean            isColor;
  130.     long            value = 0;
  131.  
  132.     Gestalt(gestaltDisplayMgrVers, (long*)&displayMgrVersion);
  133.     Gestalt(gestaltDisplayMgrAttr,&value);
  134.     displayMgrPresent=value&(1<<gestaltDisplayMgrPresent);
  135.     if (displayMgrPresent)
  136.     {
  137.         if (requestRecPtr->displayMode && requestRecPtr->depthMode)
  138.         {
  139.             if (requestRecPtr->availBitDepth == 1)    // Based on avail bit depth, 
  140.                 isColor = KMonoDev;                    // set the device to a mono device, or
  141.             else isColor = kColorDev;                // set the device to a color device
  142.             SetDeviceAttribute(requestRecPtr->screenDevice,gdDevType,isColor);        
  143.             
  144.             if (displayMgrVersion >= 0x00020000)
  145.             {
  146.                 // only call DMSetDisplayMode if we have DM2.0 is installed
  147.                 err = DMSetDisplayMode(    requestRecPtr->screenDevice,    // GDevice
  148.                         requestRecPtr->displayMode,                        // DM1.0 uses this
  149.                         &requestRecPtr->depthMode,                        // DM1.0 uses this
  150.                         (unsigned long) &(requestRecPtr->switchInfo),    // DM2.0 uses this rather than displayMode/depthMode combo
  151.                         nil);
  152.                 if (kDMDriverNotDisplayMgrAwareErr == err)
  153.                 {
  154.                     // DM not supported by driver, so all we can do is set the bit depth
  155.                     err = SetDepth (requestRecPtr->screenDevice, requestRecPtr->depthMode, gdDevType, isColor);
  156.                 }
  157.             }
  158.         }
  159.     }
  160.     return (err);
  161. }
  162.  
  163. // This extern should be removed once this function is formally defined in Displays.h
  164. extern pascal OSErr DMUseScreenPrefs(Boolean usePrefs, Handle displayState)
  165.  THREEWORDINLINE(0x303C, 0x03EC, 0xABEB);
  166.  
  167. OSErr RVSetVideoAsScreenPrefs (void)
  168. {
  169.     Handle        displaystate;
  170.     Boolean        displayMgrPresent;
  171.     long        value = 0;
  172.     OSErr        theErr = -1;        // some generic error
  173.  
  174.     Gestalt(gestaltDisplayMgrAttr,&value);
  175.     displayMgrPresent=value&(1<<gestaltDisplayMgrPresent);
  176.     if (displayMgrPresent)
  177.     {
  178.         DMBeginConfigureDisplays (&displaystate);    // Tell the world it is about to change
  179.         DMUseScreenPrefs (true, displaystate);        // Make the change
  180.         DMEndConfigureDisplays (displaystate);        // Tell the world the change is over
  181.         
  182.         theErr = noErr;    // we (maybe) set the world back to a known setting
  183.     }
  184.     return (theErr);    
  185. }
  186.  
  187. OSErr RVGetCurrentVideoSetting (VideoRequestRecPtr requestRecPtr)
  188. {
  189.     unsigned long        displayMgrVersion;
  190.     OSErr                error = paramErr;
  191.     VDSwitchInfoRec        switchInfo;
  192.  
  193.     requestRecPtr->availBitDepth            = 0;    // init to default - you can do it if it is important to you
  194.     requestRecPtr->availHorizontal            = 0;
  195.     requestRecPtr->availVertical            = 0;
  196.     requestRecPtr->availFlags                = 0;
  197.     requestRecPtr->displayMode                = -1; 
  198.     requestRecPtr->depthMode                = -1;
  199.     requestRecPtr->switchInfo.csMode        = 0;
  200.     requestRecPtr->switchInfo.csData        = 0;
  201.     requestRecPtr->switchInfo.csPage        = 0;
  202.     requestRecPtr->switchInfo.csBaseAddr    = 0;
  203.     requestRecPtr->switchInfo.csReserved    = 0;
  204.     
  205.     Gestalt(gestaltDisplayMgrVers, (long*)&displayMgrVersion);
  206.     if (requestRecPtr->screenDevice)
  207.     {
  208. //DL -    must also make sure that Display Library is installed, otherwise
  209. //        calling DMGetDisplayMode() will branch to nil.
  210. //DL        if (displayMgrVersion >= 0x00020000)
  211. #if GENERATINGCFM
  212.         if (displayMgrVersion >= 0x00020000 && (Ptr) DMGetDisplayMode != (Ptr) kUnresolvedCFragSymbolAddress)
  213. #else
  214.         if (displayMgrVersion >= 0x00020000)
  215. #endif
  216.         {    // get the info the DM 2.0 way
  217.             error = DMGetDisplayMode(requestRecPtr->screenDevice, &switchInfo);
  218.             if (noErr == error)
  219.             {
  220.                 requestRecPtr->depthMode            = switchInfo.csMode;
  221.                 requestRecPtr->displayMode            = switchInfo.csData; 
  222.                 requestRecPtr->switchInfo.csMode    = switchInfo.csMode;
  223.                 requestRecPtr->switchInfo.csData    = switchInfo.csData;
  224.             }
  225.         }
  226.     }
  227.     return (error);
  228. }
  229.  
  230. pascal Boolean ConfirmAlertFilter(DialogRef theDialog, EventRecord *theEvent, short *itemHit)
  231. {
  232.     char charCode;
  233.     Boolean enterORreturn;
  234.     Boolean returnValue = false;
  235.     WindowRef dialogWindow = GetDialogWindow(theDialog);    //DL
  236.  
  237.     if (0 == GetWRefCon(dialogWindow))
  238.         SetWRefCon (dialogWindow,TickCount());
  239.     else
  240.     {
  241.         if (GetWRefCon(dialogWindow) + kSecondsToConfirm * 60 < TickCount())
  242.         {
  243.             returnValue = true;
  244.             theEvent->what = nullEvent;
  245.             *itemHit = 1;
  246.         }
  247.         else
  248.         {
  249.             if (theEvent->what == keyDown)
  250.             {
  251.                 charCode = (char)theEvent->message & charCodeMask;
  252.                 enterORreturn = (charCode == (char)char_Return) || (charCode == (char)char_Enter);
  253.                 if (enterORreturn)
  254.                 {
  255.                     theEvent->what = nullEvent;
  256.                     returnValue = true;
  257.                     *itemHit = iRevertItem;
  258.                     if (enterORreturn && (0 != (theEvent->modifiers & optionKey)))
  259.                     {
  260.                         *itemHit = iConfirmItem;
  261.                     }
  262.                 }
  263.             }
  264.         }
  265.     }
  266.     return (returnValue);
  267. }
  268.  
  269. OSErr RVConfirmVideoRequest (VideoRequestRecPtr requestRecPtr)
  270. {
  271.     short            alertReturn;        // Alert() return value
  272.     ModalFilterUPP    confirmFilterUPP;    // got to have us one of them new fangled UPP thingies
  273.     OSErr            theErr = noErr;
  274.     
  275.     if (requestRecPtr->availFlags & 1<<kModeValidNotSafeBit)
  276.     {    // new mode is valid but not safe, so ask user to confirm
  277.         SetCursor(&qd.arrow);                                        // have to show the arrow
  278.  
  279.         confirmFilterUPP = NewModalFilterProc (ConfirmAlertFilter);    // create a new modal filter proc UPP
  280.         alertReturn = Alert(rConfirmSwtchAlrt, confirmFilterUPP);    // alert the user
  281.         DisposeRoutineDescriptor (confirmFilterUPP);                // of course there is no DisposeModalFilterProc...
  282.         
  283.         if (alertReturn != iConfirmItem)
  284.             theErr = -1;                            // tell the caller to switch back to a known setting
  285.     }
  286.     return (theErr);                                    // the mode was safe, so do nothing
  287. }
  288.  
  289.  
  290. OSErr RVRequestVideoSetting (VideoRequestRecPtr requestRecPtr)
  291. {
  292.     Boolean                            displayMgrPresent;
  293.     short                            iCount = 0;                    // just a counter of GDevices we have seen
  294.     DMDisplayModeListIteratorUPP    myModeIteratorProc = nil;    // for DM2.0 searches
  295.     Boolean                            suppliedGDevice;    
  296.     DisplayIDType                    theDisplayID;                // for DM2.0 searches
  297.     DMListIndexType                    theDisplayModeCount;        // for DM2.0 searches
  298.     DMListType                        theDisplayModeList;            // for DM2.0 searches
  299.     long                            value = 0;
  300.     GDHandle                        walkDevice = nil;            // for everybody
  301.     OSErr                            gestaltErr;
  302.     OSErr                            returnErr = -1;                // set to some generic error
  303.     unsigned long                    displayMgrVersion;
  304.     Boolean                         hasDM2 = false;
  305.     
  306.     gestaltErr = Gestalt(gestaltDisplayMgrVers, (long*)&displayMgrVersion);
  307.     if (    gestaltErr == noErr &&
  308. #if GENERATINGCFM
  309.             (Ptr) DMNewDisplayModeList != (Ptr) kUnresolvedCFragSymbolAddress &&
  310.             (Ptr) DMDisposeList != (Ptr) kUnresolvedCFragSymbolAddress &&
  311. #endif
  312.             displayMgrVersion >= 0x00020000    )
  313.     {
  314.         hasDM2 = true;                // Check for the presence of DM 2.0 before calling DMNewDisplayModeList() and DMDisposeList()
  315.     }
  316.  
  317.     Gestalt(gestaltDisplayMgrAttr,&value);
  318.     displayMgrPresent=value&(1<<gestaltDisplayMgrPresent);
  319.     displayMgrPresent=displayMgrPresent && hasDM2;
  320.     
  321.     if (displayMgrPresent)        // only jump in if we have DM 2.0
  322.     {
  323.         // init the needed data before we start
  324.         if (requestRecPtr->screenDevice)                            // user wants a specifc device?
  325.         {
  326.             walkDevice = requestRecPtr->screenDevice;
  327.             suppliedGDevice = true;
  328.         }
  329.         else
  330.         {
  331.             walkDevice = DMGetFirstScreenDevice (dmOnlyActiveDisplays);            // for everybody
  332.             suppliedGDevice = false;
  333.         }
  334.         
  335.         myModeIteratorProc = NewDMDisplayModeListIteratorProc(ModeListIterator);    // for DM2.0 searches
  336.     
  337.         // Note that we are hosed if somebody changes the gdevice list behind our backs while we are iterating....
  338.         // ...now do the loop if we can start
  339.         if( walkDevice && myModeIteratorProc)
  340.         {
  341.             do // start the search
  342.             {
  343.                 iCount++;        // GDevice we are looking at (just a counter)
  344.                 if( noErr == DMGetDisplayIDByGDevice( walkDevice, &theDisplayID, false ) )    // DM1.0 does not need this, but it fits in the loop
  345.                 {
  346.                     theDisplayModeCount = 0;    // for DM2.0 searches
  347.                     if (noErr == DMNewDisplayModeList(theDisplayID, 0, 0, &theDisplayModeCount, &theDisplayModeList) )
  348.                     {
  349.                         // search NuBus & PCI the new kool way through Display Manager 2.0
  350.                         GetRequestTheDM2Way (requestRecPtr, walkDevice, myModeIteratorProc, theDisplayModeCount, &theDisplayModeList);
  351.                         DMDisposeList(theDisplayModeList);    // now toss the lists for this gdevice and go on to the next one
  352.                     }
  353.                 }
  354.             } while ( !suppliedGDevice && nil != (walkDevice = DMGetNextScreenDevice ( walkDevice, dmOnlyActiveDisplays )) );    // go until no more gdevices
  355.         }
  356.         
  357.         if( myModeIteratorProc )
  358.             DisposeRoutineDescriptor(myModeIteratorProc);
  359.         
  360.         //••• WE MAY NOT HAVE FOUND A REQUEST FROM GETREQUESTTHEDM2WAY() in whicxh case the requestRec.displayMode & requestRec.depthMode fields will be nil
  361.         returnErr = noErr;    // we were able to try to look for a match
  362.     }
  363.     return (returnErr);
  364. }
  365.  
  366. pascal void ModeListIterator(void *userData, DMListIndexType, DMDisplayModeListEntryPtr displaymodeInfo)
  367. {
  368.     unsigned long            depthCount;
  369.     short                    iCount;
  370.     ListIteratorDataRec        *myIterateData        = (ListIteratorDataRec*) userData;
  371.     DepthInfo                *myDepthInfo;
  372.     
  373.     // set user data in a round about way
  374.     myIterateData->displayModeTimingInfo        = *displaymodeInfo->displayModeTimingInfo;
  375.     
  376.     // now get the DMDepthInfo info into memory we own
  377.     depthCount = displaymodeInfo->displayModeDepthBlockInfo->depthBlockCount;
  378.     myDepthInfo = (DepthInfo*)NewPtrClear(depthCount * sizeof(DepthInfo));
  379.  
  380.     // set the info for the caller
  381.     myIterateData->depthBlockCount = depthCount;
  382.     myIterateData->depthBlocks = myDepthInfo;
  383.  
  384.     // and fill out all the entries
  385.     if (depthCount) for (iCount=0; iCount < depthCount; iCount++)
  386.     {
  387.         myDepthInfo[iCount].depthSwitchInfo = 
  388.             *displaymodeInfo->displayModeDepthBlockInfo->depthVPBlock[iCount].depthSwitchInfo;
  389.         myDepthInfo[iCount].depthVPBlock = 
  390.             *displaymodeInfo->displayModeDepthBlockInfo->depthVPBlock[iCount].depthVPBlock;
  391.     }
  392. }
  393.  
  394. void GetRequestTheDM2Way (    VideoRequestRecPtr requestRecPtr,
  395.                             GDHandle walkDevice,
  396.                             DMDisplayModeListIteratorUPP myModeIteratorProc,
  397.                             DMListIndexType theDisplayModeCount,
  398.                             DMListType *theDisplayModeList)
  399. {
  400.     short                    jCount;
  401.     short                    kCount;
  402.     ListIteratorDataRec        searchData;
  403.  
  404.     searchData.depthBlocks = nil;
  405.     // get the mode lists for this GDevice
  406.     for (jCount=0; jCount<theDisplayModeCount; jCount++)        // get info on all the resolution timings
  407.     {
  408.         DMGetIndexedDisplayModeFromList(*theDisplayModeList, jCount, 0, myModeIteratorProc, &searchData);
  409.         
  410.         // for all the depths for this resolution timing (mode)...
  411.         if (searchData.depthBlockCount) for (kCount = 0; kCount < searchData.depthBlockCount; kCount++)
  412.         {
  413.             // only if the mode is valid and is safe or we override it with the kAllValidModesBit request flag
  414.             if    (    searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeValid && 
  415.                     (    searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeSafe ||
  416.                         requestRecPtr->requestFlags & 1<<kAllValidModesBit
  417.                     )
  418.                 )
  419.             {
  420.                 if (FindBestMatch (    requestRecPtr,
  421.                                     searchData.depthBlocks[kCount].depthVPBlock.vpPixelSize,
  422.                                     searchData.depthBlocks[kCount].depthVPBlock.vpBounds.right,
  423.                                     searchData.depthBlocks[kCount].depthVPBlock.vpBounds.bottom))
  424.                 {
  425.                     requestRecPtr->screenDevice = walkDevice;
  426.                     requestRecPtr->availBitDepth = searchData.depthBlocks[kCount].depthVPBlock.vpPixelSize;
  427.                     requestRecPtr->availHorizontal = searchData.depthBlocks[kCount].depthVPBlock.vpBounds.right;
  428.                     requestRecPtr->availVertical = searchData.depthBlocks[kCount].depthVPBlock.vpBounds.bottom;
  429.                     
  430.                     // now set the important info for DM to set the display
  431.                     requestRecPtr->depthMode = searchData.depthBlocks[kCount].depthSwitchInfo.csMode;
  432.                     requestRecPtr->displayMode = searchData.depthBlocks[kCount].depthSwitchInfo.csData;
  433.                     requestRecPtr->switchInfo = searchData.depthBlocks[kCount].depthSwitchInfo;
  434.                     if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeSafe)
  435.                         requestRecPtr->availFlags = 0;                            // mode safe
  436.                     else requestRecPtr->availFlags = 1<<kModeValidNotSafeBit;    // mode valid but not safe, requires user validation of mode switch
  437.     
  438.                 }
  439.             }
  440.  
  441.         }
  442.     
  443.         if (searchData.depthBlocks)
  444.         {
  445.             DisposePtr ((Ptr)searchData.depthBlocks);    // toss for this timing mode of this gdevice
  446.             searchData.depthBlocks = nil;                // init it just so we know
  447.         }
  448.     }
  449. }
  450.  
  451. Boolean FindBestMatch (VideoRequestRecPtr requestRecPtr, short bitDepth, unsigned long horizontal, unsigned long vertical)
  452. {
  453.     // •• do the big comparison ••
  454.     // first time only if    (no mode yet) and
  455.     //                        (bounds are greater/equal or kMaximizeRes not set) and
  456.     //                        (depth is less/equal or kShallowDepth not set) and
  457.     //                        (request match or kAbsoluteRequest not set)
  458.     if    (    nil == requestRecPtr->displayMode
  459.             &&
  460.             (    (horizontal >= requestRecPtr->reqHorizontal &&
  461.                 vertical >= requestRecPtr->reqVertical)
  462.                 ||                                                        
  463.                 !(requestRecPtr->requestFlags & 1<<kMaximizeResBit)    
  464.             )
  465.             &&
  466.             (    bitDepth <= requestRecPtr->reqBitDepth ||    
  467.                 !(requestRecPtr->requestFlags & 1<<kShallowDepthBit)        
  468.             )
  469.             &&
  470.             (    (horizontal == requestRecPtr->reqHorizontal &&    
  471.                 vertical == requestRecPtr->reqVertical &&
  472.                 bitDepth == requestRecPtr->reqBitDepth)
  473.                 ||
  474.                 !(requestRecPtr->requestFlags & 1<<kAbsoluteRequestBit)    
  475.             )
  476.         )
  477.         {
  478.             // go ahead and set the new values
  479.             return (true);
  480.         }
  481.     else    // can we do better than last time?
  482.     {
  483.         // if    (kBitDepthPriority set and avail not equal req) and
  484.         //        ((depth is greater avail and depth is less/equal req) or kShallowDepth not set) and
  485.         //        (avail depth less reqested and new greater avail) or
  486.         //        (request match or kAbsoluteRequest not set)
  487.         if    (    (    requestRecPtr->requestFlags & 1<<kBitDepthPriorityBit && 
  488.                     requestRecPtr->availBitDepth != requestRecPtr->reqBitDepth
  489.                 )
  490.                 &&
  491.                 (    (    bitDepth > requestRecPtr->availBitDepth &&
  492.                         bitDepth <= requestRecPtr->reqBitDepth
  493.                     )
  494.                     ||
  495.                     !(requestRecPtr->requestFlags & 1<<kShallowDepthBit)    
  496.                 )
  497.                 &&
  498.                 (    requestRecPtr->availBitDepth < requestRecPtr->reqBitDepth &&
  499.                     bitDepth > requestRecPtr->availBitDepth    
  500.                 )
  501.                 &&
  502.                 (    (horizontal == requestRecPtr->reqHorizontal &&    
  503.                     vertical == requestRecPtr->reqVertical &&
  504.                     bitDepth == requestRecPtr->reqBitDepth)
  505.                     ||
  506.                     !(requestRecPtr->requestFlags & 1<<kAbsoluteRequestBit)    
  507.                 )
  508.             )
  509.         {
  510.             // go ahead and set the new values
  511.             return (true);
  512.         }
  513.         else
  514.         {
  515.             // match resolution: minimize Δh & Δv
  516.             if    (    abs((requestRecPtr->reqHorizontal - horizontal)) <=
  517.                     abs((requestRecPtr->reqHorizontal - requestRecPtr->availHorizontal)) &&
  518.                     abs((requestRecPtr->reqVertical - vertical)) <=
  519.                     abs((requestRecPtr->reqVertical - requestRecPtr->availVertical))
  520.                 )
  521.             {
  522.                 // now we have a smaller or equal delta
  523.                 //    if (h or v greater/equal to request or kMaximizeRes not set) 
  524.                 if (    (horizontal >= requestRecPtr->reqHorizontal &&
  525.                         vertical >= requestRecPtr->reqVertical)
  526.                         ||
  527.                         !(requestRecPtr->requestFlags & 1<<kMaximizeResBit)
  528.                     )
  529.                 {
  530.                     // if    (depth is equal or kBitDepthPriority not set) and
  531.                     //        (depth is less/equal or kShallowDepth not set) and
  532.                     //        ([h or v not equal] or [avail depth less reqested and new greater avail] or depth equal avail) and
  533.                     //        (request match or kAbsoluteRequest not set)
  534.                     if    (    (    requestRecPtr->availBitDepth == bitDepth ||            
  535.                                 !(requestRecPtr->requestFlags & 1<<kBitDepthPriorityBit)
  536.                             )
  537.                             &&
  538.                             (    bitDepth <= requestRecPtr->reqBitDepth ||    
  539.                                 !(requestRecPtr->requestFlags & 1<<kShallowDepthBit)        
  540.                             )
  541.                             &&
  542.                             (    (requestRecPtr->availHorizontal != horizontal ||
  543.                                 requestRecPtr->availVertical != vertical)
  544.                                 ||
  545.                                 (requestRecPtr->availBitDepth < requestRecPtr->reqBitDepth &&
  546.                                 bitDepth > requestRecPtr->availBitDepth)
  547.                                 ||
  548.                                 (bitDepth == requestRecPtr->reqBitDepth)
  549.                             )
  550.                             &&
  551.                             (    (horizontal == requestRecPtr->reqHorizontal &&    
  552.                                 vertical == requestRecPtr->reqVertical &&
  553.                                 bitDepth == requestRecPtr->reqBitDepth)
  554.                                 ||
  555.                                 !(requestRecPtr->requestFlags & 1<<kAbsoluteRequestBit)    
  556.                             )
  557.                         )
  558.                     {
  559.                         // go ahead and set the new values
  560.                         return (true);
  561.                     }
  562.                 }
  563.             }
  564.         }
  565.     }
  566.     return (false);
  567. }
  568.